package com.liang.manage.auth.facade.server.iml;

import com.liang.manage.auth.facade.dto.user.UserRoleDTO;
import com.liang.manage.auth.facade.dto.user.UserRoleOrgDTO;
import com.liang.manage.auth.facade.entity.UserRolePo;
import com.liang.manage.auth.facade.entity.UserRolePoExample;
import com.liang.manage.auth.facade.mapper.UserRolePoMapper;
import com.liang.manage.auth.facade.mapstruct.UserRoleMS;
import com.liang.manage.auth.facade.server.UserRoleService;

import com.liang.nansheng.common.auth.UserSsoDTO;
import com.liang.nansheng.common.enums.ResponseCode;
import com.liang.nansheng.common.web.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 马亮
 * @date 2021/4/25 15:21
 */
@Slf4j
@Service
@Component
public class UserRoleServiceImpl implements UserRoleService {
    @Autowired
    private UserRolePoMapper userRolePoMapper;

    /**
     * 根据用户id集合获取用户角色信息
     *
     * @param userIds
     * @return
     */
    @Override
    public List<UserRoleDTO> getByUserIds(List<Long> userIds) {
        UserRolePoExample example = new UserRolePoExample();
        example.createCriteria().andIsDeletedEqualTo(false)
                .andUserIdIn(userIds);

        return UserRoleMS.INSTANCE.toDTO(userRolePoMapper.selectByExample(example));
    }

    /**
     * 根据角色id集合获取用户角色信息
     *
     * @param roleIds
     * @return
     */
    @Override
    public List<UserRoleDTO> getByRoleIds(List<Integer> roleIds) {
        UserRolePoExample example = new UserRolePoExample();
        example.createCriteria().andIsDeletedEqualTo(false)
                .andRoleIdIn(roleIds);

        return UserRoleMS.INSTANCE.toDTO(userRolePoMapper.selectByExample(example));
    }

    /**
     * 根据角色id删除用户角色
     *
     * @param roleId
     * @param currentUser
     * @return
     */
    @Override
    public Boolean deleteByRoleId(Integer roleId, UserSsoDTO currentUser) {
        UserRolePoExample example = new UserRolePoExample();
        example.createCriteria().andIsDeletedEqualTo(false)
                .andRoleIdEqualTo(roleId);

        UserRolePo userRolePo = new UserRolePo();
        userRolePo.setIsDeleted(true);
        userRolePo.setRoleId(roleId);
        userRolePo.setUpdateUser(currentUser.getUserId());
        userRolePo.setUpdateTime(LocalDateTime.now());

        if (userRolePoMapper.updateByExampleSelective(userRolePo, example) <= 0) {
            throw BusinessException.build(ResponseCode.OPERATE_FAIL, "删除用户角色失败");
        }

        return true;
    }

    /**
     * 更新用户角色
     *
     * @param userRoleOrgDTO
     * @param currentUser
     * @return
     */
    @Override
    public Boolean updateUserRole(UserRoleOrgDTO userRoleOrgDTO, UserSsoDTO currentUser) {
        List<UserRoleDTO> userRoleDTOS = getByUserIds(Collections.singletonList(userRoleOrgDTO.getUserId()));
        Map<Integer, Integer> map = userRoleDTOS.stream()
                .collect(Collectors.toMap(UserRoleDTO::getRoleId, UserRoleDTO::getId, (v1, v2) -> v1));
        userRoleOrgDTO.getRoleIds().forEach(roleId -> {
            // 不需要处理的角色
            if (map.containsKey(roleId)) {
                map.remove(roleId);
                // 需要新增的角色
            } else {
                UserRolePo userRolePo = new UserRolePo();
                userRolePo.setIsDeleted(false);
                userRolePo.setUserId(userRoleOrgDTO.getUserId());
                userRolePo.setCreateUser(currentUser.getUserId());
                userRolePo.setUpdateUser(currentUser.getUserId());
                LocalDateTime now = LocalDateTime.now();
                userRolePo.setCreateTime(now);
                userRolePo.setUpdateTime(now);
                userRolePo.setRoleId(roleId);
                if (userRolePoMapper.insertSelective(userRolePo) <= 0) {
                    throw BusinessException.build(ResponseCode.OPERATE_FAIL, "更新用户角色失败");
                }
            }
        });

        // 需要移除的角色
        map.forEach((k, v) -> {
            UserRolePo userRolePo = new UserRolePo();
            userRolePo.setId(v);
            userRolePo.setIsDeleted(true);
            userRolePo.setUpdateUser(currentUser.getUserId());
            userRolePo.setUpdateTime(LocalDateTime.now());
            if (userRolePoMapper.updateByPrimaryKeySelective(userRolePo) <= 0) {
                throw BusinessException.build(ResponseCode.OPERATE_FAIL, "更新用户角色失败");
            }
        });

        return true;
    }
}